package one.stand.controller;

import com.google.common.collect.Lists;
import com.jmp.api.dto.OrdersInfoResponse;
import com.jmp.api.dto.OrdersListResponse;
import com.jmp.autocofiguration.web.interceptor.SecurityAuthCheck;
import com.jmp.base.dto.*;
import com.jmp.feign.OrderFeign;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import one.stand.advice.ResultEnum;
import one.stand.dto.Company2Dto;
import one.stand.dto.ConvertUtils;
import one.stand.dto.UserDto;
import one.stand.enums.OrderStateEnum;
import one.stand.model.BusinessCard;
import one.stand.model.ResultModel;
import one.stand.request.OrdersRequest;
import one.stand.service.BusinessCardBaseService;
import one.stand.service.CompanyBaseService;
import one.stand.service.user.UserAdminService;
import one.stand.util.AssertUtil;
import one.stand.util.MoneyUtil;
import one.stand.util.RequestContext;
import one.stand.util.RequestContextHolder;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 订单信息
 *
 * @author
 */
@RestController
@RequestMapping("crmApi/orders")
public class OrdersController extends BaseController {
    @Autowired
    private OrderFeign orderFeign;

    @Autowired
    private UserAdminService userAdminService;
    @Autowired
    private BusinessCardBaseService businessCardBaseService;
    @Autowired
    private CompanyBaseService companyBaseService;

    @PostMapping("/selectOrdersInfo")
    @ApiOperation(value = "根据公司查询订单(订单状态（1待付款，2待发货，3待收货，4已完成，5交易取消，6退款成功）)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderState", value = "订单状态（1待付款，2待发货，3待收货，4已完成，5交易取消，6退款成功）", required = true, paramType = "Integer"),
    })
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<List<OrdersListResponse>> selectOrdersInfo(@RequestAttribute OrdersRequest request) {
        final RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();
        ResultModel<OrderListVo> resultModel = orderFeign.list(OrderListDto.builder()
                .companyId(optUser.getCompanyId())
                .status(request.getOrderState() == 5 ? 6 : request.getOrderState())
                .build());
        AssertUtil.isTrue(resultModel);

        Company2Dto company2Dto = companyBaseService.get2(optUser.getCompanyId());

        List<OrdersListResponse> responses = ConvertUtils.list(resultModel.getData().getOrderPage().getList(), order -> {

            UserDto user = userAdminService.get(optUser.getUserId());
            BusinessCard card = businessCardBaseService.getByUserId(user.getUserId());
            Integer allNum = order.getGoodsList().stream().mapToInt(OrderListVo.Goods::getSkuNum).sum();

            return OrdersListResponse.builder()
                    .ordersId(order.getOrderId())
                    .orderPrice(MoneyUtil.getMoneyInt(order.getOrderPrice()))
                    .orderState(order.getOrderState())
                    .refundState(order.getRefundState())
                    .refundRemark(order.getRefundRemark())
                    .payPrice(MoneyUtil.getMoneyInt(order.getOrderPrice()))

                    .companyId(order.getCompanyId())
                    .companyName(company2Dto.getCompanyName())

                    .userId(user.getUserId())
                    .logo(user.getUserImg())
                    .name(user.getName())
                    .phone(user.getPhone())
                    .personalWx(Objects.nonNull(card) ? card.getPersonalWx() : null)

                    .ordersModelList(ConvertUtils.list(order.getGoodsList(), goods -> {
                        return OrdersListResponse.Goods.builder()
                                .goodsId(goods.getGoodsId())
                                .goodsName(goods.getGoodsName())
                                .photoUrl(goods.getGoodsPhoto())
                                .specAttribute(StringUtils.EMPTY)
                                .specName(goods.getSkuName())
                                .num(goods.getSkuNum())
                                .price(MoneyUtil.getMoneyInt(goods.getPrice()))
                                .allPrice(MoneyUtil.getMoneyInt(goods.getPrice().multiply(BigDecimal.valueOf(goods.getSkuNum()))))
                                .cardId(goods.getCardId())
                                .build();
                    }))
                    .allNum(allNum)

                    .build();
        });
        return ResultModel.success(responses);
    }

    @PostMapping("/getOrdersInfo")
    @ApiOperation(value = "查询订单详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ordersId", value = "订单id", required = true, paramType = "Integer"),
    })
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<List<OrdersInfoResponse>> getOrdersInfo(@RequestAttribute OrdersRequest request) {
        AssertUtil.nonNull(request.getOrdersId(), ResultEnum.NO_PARAM);

        final RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();

        List<OrdersInfoResponse> list = Lists.newArrayList();
        ResultModel<OrderDetailVo> resultModel = orderFeign.detail(OrderDetailDto.builder().orderId(request.getOrdersId()).build());
        AssertUtil.isTrue(resultModel);
        OrderDetailVo vo = resultModel.getData();

        Company2Dto company2Dto = companyBaseService.get2(vo.getCompanyId());
        Integer allNum = vo.getGoodsList().stream().mapToInt(OrderDetailVo.Goods::getSkuNum).sum();
        UserDto user = userAdminService.get(optUser.getUserId());
        BusinessCard card = businessCardBaseService.getByUserId(user.getUserId());

        list.add(OrdersInfoResponse.builder()
                .ordersId(vo.getOrderId())
                .ordersNo(vo.getOrderNo())
                .tradeNo(vo.getTradeNo())
                .orderPrice(MoneyUtil.getMoneyInt(vo.getOrderPrice()))
                .orderState(vo.getOrderState())
                .createTime(new Date(vo.getOrderCreateTime()))
                .payType(vo.getPayType())
                .payPrice(MoneyUtil.getMoneyInt(vo.getPayPrice()))
                .payTime(Objects.nonNull(vo.getOrderPayTime()) ? new Date(vo.getOrderPayTime()) : null)
                .deliveryType(vo.getDeliveryType())
                .remark(vo.getOrderRemark())

                .refundState(vo.getRefundState())
                .refundRemark(vo.getRefundRemark())

                .addressId(vo.getAddressId())
                .detailedAddress(vo.getAddressDetail())
                .receiveName(vo.getAddressName())
                .receivePhone(vo.getAddressPhone())

                .companyId(company2Dto.getCompanyId())
                .companyName(company2Dto.getCompanyName())

                .userId(user.getUserId())
                .logo(user.getUserImg())
                .name(user.getName())
                .phone(user.getPhone())
                .personalWx(Objects.nonNull(card) ? card.getPersonalWx() : null)

                .ordersModelList(ConvertUtils.list(vo.getGoodsList(), goods -> {
                    return OrdersInfoResponse.Goods.builder()
                            .goodsId(goods.getGoodsId())
                            .goodsName(goods.getGoodsName())
                            .photoUrl(goods.getGoodsPhoto())
                            .specAttribute(StringUtils.EMPTY)
                            .specName(goods.getSkuName())
                            .num(goods.getSkuNum())
                            .price(MoneyUtil.getMoneyInt(goods.getPrice()))
                            .allPrice(MoneyUtil.getMoneyInt(goods.getPrice().multiply(BigDecimal.valueOf(goods.getSkuNum()))))
                            .cardId(goods.getCardId())
                            .build();
                }))
                .allNum(allNum)
                .build());

        return ResultModel.success(list);
    }

    @PostMapping("/updateOrderState")
    @ApiOperation(value = "撤销订单，确认发货")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ordersId", value = "订单id", required = true, paramType = "Integer"),
            @ApiImplicitParam(name = "orderState", value = "订单状态（1待付款，2待发货，3待收货，4已完成，5交易取消，6退款成功）", required = true, paramType = "Integer"),
    })
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel updateOrderState(@RequestAttribute OrdersRequest request) {
        if (OrderStateEnum.WAIT_RECEIVING.getCode().equals(request.getOrderState())) {
            ResultModel resultModel = orderFeign.send(OrderSendRequest.builder()
                    .orderId(request.getOrdersId())
                    .deliveryCompany(null)
                    .deliveryNo(null)
                    .build());
            AssertUtil.isTrue(resultModel);
        } else if (OrderStateEnum.CANCEL.getCode().equals(request.getOrderState())) {
            ResultModel resultModel = orderFeign.cancel(OrderCancelDto.builder()
                    .orderId(request.getOrdersId())
                    .build());
            AssertUtil.isTrue(resultModel);
        } else {
            AssertUtil.fail(ResultEnum.FAIL);
        }
        return ResultModel.success();
    }

    @PostMapping("/updateRefundState")
    @ApiOperation(value = "修改订单退款状态1未申请，2退款申请中，3退款成功")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ordersId", value = "订单id", required = true, paramType = "Integer"),
            @ApiImplicitParam(name = "refundState", value = "退款状态1未申请(拒绝)，2退款申请中，3退款成功", required = true, paramType = "Integer"),
    })
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel updateRefundState(@RequestAttribute OrdersRequest request) {

        return crmFegin.updateRefundState(request);
    }

    @RequestMapping(value = "/backRefund")
    @ApiOperation(value = "退款异步回调")
    public String backRefund(HttpServletRequest request) {
        try {
            BufferedReader reader = request.getReader();
            String line = "";
            StringBuffer inputString = new StringBuffer();
            while ((line = reader.readLine()) != null) {
                inputString.append(line);
            }
            request.getReader().close();
            return crmFegin.backRefund(inputString.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fail();
    }

    public String fail() {
        return "<xml> \n" +
                "  <return_code><![CDATA[fail]]></return_code>\n" +
                "  <return_msg><![CDATA[OK]]></return_msg>\n" +
                "</xml>";
    }
}
